package com.baiytfp.hf.HFDataExchange.common.filter;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;

import com.baiytfp.hf.baiytfp.hfutils.HFLog;

/**
 * 功能描述：ip和域名黑名单过滤器。
 * 防止Web模块与后台管理模板放在同一个工程，Web模块需要部署在外网，后台管理模板需要部署在内网时，
 * 由于后台管理模板需要使用HFDataExchange登录，但是外网环境不希望被允许访问后台管理模块，所以可以通过打开
 * 该过滤器对外网访问ip和域名进行黑名单过滤。
 * @since 1.0.1
 * @author ChenJiaMing By 20180116
 *
 */
public class DnfFilter implements Filter {
	
	private Logger logger = HFLog.getLogger(DnfFilter.class);
	
	private final String CONFIG_FILE = "config/dnfBlack.txt";
	
	private List<String> dnfBlackList;
	
	/**
	 * 初始化Filter时执行
	 */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
		logger.info("初始化DnfFilter");
		
		// 定义域名黑名单文件
		File dnfBlackFile = null;
		
		try {
			// 读取域名黑名单配置文件
			dnfBlackFile = new File(this.getClass().getClassLoader().getResource(this.CONFIG_FILE).getFile());
			// 将文件字符串读取到List中
			dnfBlackList = FileUtils.readLines(dnfBlackFile, "UTF-8");
			logger.info(dnfBlackList.toString());
		} catch (IOException e) {
			logger.error("加载域名黑名单文件失败，", e);
			throw new RuntimeException(e);
		}
		
	}
	
	/**
	 * 执行过滤
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		
		// 获取部署环境ip地址
		String ip = req.getLocalAddr();
		// 获取部署环境域名
		String host = req.getLocalName();
		logger.info("执行域名过滤：" + ip + "," + host);
		
		// 判断是否属于黑名单
		if(isDnfBlack(ip) || isDnfBlack(host)){
			// 属于黑名单则重定向到Web首页
			resp.sendRedirect("/");
			return;
		}
		
		// 不属于黑名单则放行
		chain.doFilter(request, response);
	}
	
	/**
	 * 销毁Filter时执行
	 */
	@Override
	public void destroy() {
		return;
	}
	
	/**
	 * 判断是否为域名黑名单
	 * @param dn
	 * @return
	 */
	private boolean isDnfBlack(String dn){
		boolean result = false;
		if(dn == null || "".equals(dn)){
			result = Boolean.TRUE;
		}else{
			if(dnfBlackList != null){
				for (String dnfb : dnfBlackList) {
					if(dn.equals(dnfb)){
						result = Boolean.TRUE;
						break;
					}
				}
			}
		}
		return result;
	}

}
